#include <gtk/gtk.h>

enum
{
   TITLE_COLUMN,
   AUTHOR_COLUMN,
   CHECKED_COLUMN,
   N_COLUMNS
};

static void populate_tree_model(GtkTreeStore *store);

/* Prototype for selection handler callback */
static void tree_selection_changed_cb (GtkTreeSelection *selection,
                                       gpointer data);
static void setup_tree (void);


int main(int argc, char *argv[]) {
    gtk_init(&argc, &argv);
    setup_tree();
    g_main_loop_run(g_main_loop_new(NULL, TRUE));
    return 0;
}

static void populate_tree_model(GtkTreeStore *store) {
    GtkTreeIter   iter;
    GtkTreeIter   iter1; //parent
    GtkTreeIter   iter2; //child
    gtk_tree_store_append (store, &iter, NULL);  /* Acquire an iterator */
    
    gtk_tree_store_set (store, &iter,
                        TITLE_COLUMN, "The Principle of Reason",
                        AUTHOR_COLUMN, "Martin Heidegger",
                        CHECKED_COLUMN, FALSE,
                        -1);
    gtk_tree_store_append (store, &iter1, NULL);  /* Acquire a top-level iterator */
    gtk_tree_store_set (store, &iter1,
                        TITLE_COLUMN, "The Art of Computer Programming",
                        AUTHOR_COLUMN, "Donald E. Knuth",
                        CHECKED_COLUMN, FALSE,
                        -1);
 
    gtk_tree_store_append (store, &iter2, &iter1);  /* Acquire a child iterator */
    gtk_tree_store_set (store, &iter2,
                        TITLE_COLUMN, "Volume 1: Fundamental Algorithms",
                        -1);
    
    gtk_tree_store_append (store, &iter2, &iter1);
    gtk_tree_store_set (store, &iter2,
                        TITLE_COLUMN, "Volume 2: Seminumerical Algorithms",
                        -1);
    
    gtk_tree_store_append (store, &iter2, &iter1);
    gtk_tree_store_set (store, &iter2,
                        TITLE_COLUMN, "Volume 3: Sorting and Searching",
                        -1);   
}

static void
tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data)
{
        GtkTreeIter iter;
        GtkTreeModel *model;
        gchar *author;

        if (gtk_tree_selection_get_selected (selection, &model, &iter))
        {
                gtk_tree_model_get (model, &iter, AUTHOR_COLUMN, &author, -1);

                g_print ("You selected a book by %s\n", author);

                g_free (author);
        }
}

static void
setup_tree (void)
{
   GtkTreeStore *store;
   GtkWidget *tree;
   GtkTreeViewColumn *column;
   GtkCellRenderer *renderer;

   /* Create a model.  We are using the store model for now, though we
    * could use any other GtkTreeModel */
   store = gtk_tree_store_new (N_COLUMNS,
                               G_TYPE_STRING,
                               G_TYPE_STRING,
                               G_TYPE_BOOLEAN);

   /* custom function to fill the model with data */
   populate_tree_model (store);

   /* Create a view */
   tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));

   /* The view now holds a reference.  We can get rid of our own
    * reference */
   g_object_unref (G_OBJECT (store));

   /* Create a cell render and arbitrarily make it red for demonstration
    * purposes */
   renderer = gtk_cell_renderer_text_new ();
   g_object_set (G_OBJECT (renderer),
                 "foreground", "red",
                 NULL);

   /* Create a column, associating the "text" attribute of the
    * cell_renderer to the first column of the model */
   column = gtk_tree_view_column_new_with_attributes ("Author", renderer,
                                                      "text", AUTHOR_COLUMN,
                                                      NULL);

   /* Add the column to the view. */
   gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);

   /* Second column.. title of the book. */
   renderer = gtk_cell_renderer_text_new ();
   column = gtk_tree_view_column_new_with_attributes ("Title",
                                                      renderer,
                                                      "text", TITLE_COLUMN,
                                                      NULL);
   gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);

   /* Last column.. whether a book is checked out. */
   renderer = gtk_cell_renderer_toggle_new ();
   column = gtk_tree_view_column_new_with_attributes ("Checked out",
                                                      renderer,
                                                      "active", CHECKED_COLUMN,
                                                      NULL);
   gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);


   /* Setup the selection handler */
   GtkTreeSelection *select;
   
   select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
   gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
   g_signal_connect (G_OBJECT (select), "changed",
                     G_CALLBACK (tree_selection_changed_cb),
                     NULL); 

   /* Now we can manipulate the view just like any other GTK widget */
   GtkWidget *win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
   gtk_widget_set_size_request(win, 600, 200);
   gtk_container_add(GTK_CONTAINER(win), tree);
    
   gtk_widget_show_all(win);
   
}

